package com.xbongbong.paas.service.workflow.setting.impl;

import com.alibaba.fastjson.JSON;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.config.constant.WorkflowConstant;
import com.xbongbong.paas.config.enums.WorkflowTriggerMethodEnum;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.pojo.workflow.NodeCoreConfigurationPojo;
import com.xbongbong.paas.pojo.workflow.WorkflowNodeTreePojo;
import com.xbongbong.paas.pojo.workflow.nodes.vo.SendMsgNodeVO;
import com.xbongbong.paas.pojo.workflow.nodes.vo.WorkflowNodeGetVO;
import com.xbongbong.paas.pojo.workflow.settings.WorkflowGetPojo;
import com.xbongbong.paas.pojo.workflow.settings.vo.WorkflowEnableVO;
import com.xbongbong.paas.service.workflow.setting.AbstractWorkflowNodeSettings;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.WorkflowNodeUtil;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.domain.entity.ext.WorkflowNodeEntityExt;
import com.xbongbong.workflow.enums.WorkflowNodeTypeEnum;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.pojo.nodes.SendMsgNode;
import com.xbongbong.workflow.pojo.nodes.WorkflowOptionalRangePojo;
import com.xbongbong.workflow.pojo.nodes.WorkflowTitlePojo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/05/21 14:35
 */
@Service("workflowNodeSendMessageSettings")
public class WorkflowNodeSendMessageSettings extends AbstractWorkflowNodeSettings {

    private static String MESSAGE_CONSTANT = "constant.WorkflowNodeSendMessageSettings.message_constant";

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowNodeSendMessageSettings.class);

    @Resource
    private WorkflowNodeModel workflowNodeModel;



    @Override
    public Integer type() {
        return WorkflowNodeTypeEnum.SEND_MESSAGE_NODE.getType();
    }

    @Override
    public WorkflowNodeTreePojo getContent(WorkflowNodeEntity workflowNodeEntity, WorkflowGetPojo workflowGetPojo) throws XbbException {
        WorkflowNodeTreePojo workflowNodeTreePojo = new WorkflowNodeTreePojo();
        try {
            SendMsgNode sendMsgNode = JSON.parseObject(workflowNodeEntity.getConfigData(), SendMsgNode.class);
            if (Objects.isNull(sendMsgNode) || Objects.isNull(sendMsgNode.getMessageRecipient())) {
                return workflowNodeTreePojo;
            }
            List<WorkflowTitlePojo> messageContent = sendMsgNode.getMessageContent();
            List<String> messageList = new ArrayList<>();
            messageContent.forEach(item->{
                if (StringUtil.isNotEmpty(item.getContent())) {
                    messageList.add(item.getContent());
                } else {
                    Long formId = item.getFormId();
                    Integer businessType = item.getBusinessType();
                    Map<String, FieldAttrEntity> explainMap = WorkflowNodeUtil.getExplainMap(workflowGetPojo, businessType, formId);
                    if (explainMap.containsKey(item.getAttr())) {
                        FieldAttrEntity fieldAttrEntity = explainMap.get(item.getAttr());
                        if (!ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
                            messageList.add(fieldAttrEntity.getAttrName());
                        }
                    }
                }
            });
            List<String> contentList = new ArrayList<>();
            workflowNodeTreePojo = getSendMsgNodeNameAndAvatar(sendMsgNode.getMessageRecipient(), workflowGetPojo);
            contentList.addAll((List) workflowNodeTreePojo.getContent());
            String message = String.format(I18nMessageUtil.getMessage(MESSAGE_CONSTANT), StringUtils.join(messageList));
            contentList.add(message);
            workflowNodeTreePojo.setContent(contentList);

        } catch (Exception e) {
            LOGGER.error("WorkflowNodeSendMessageSettings.getContent error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return workflowNodeTreePojo;
    }

    @Override
    public WorkflowNodeGetVO get(WorkflowNodeEntity workflowNodeEntity) throws XbbException {
        try {
            SendMsgNodeVO sendMsgNode = JSON.parseObject(workflowNodeEntity.getConfigData(), SendMsgNodeVO.class);
            NodeCoreConfigurationPojo nodeCoreConfigurationPojo = new NodeCoreConfigurationPojo();
            nodeCoreConfigurationPojo.setSendMsgNode(sendMsgNode);

            WorkflowNodeGetVO workflowNodeGetVO = new WorkflowNodeGetVO(workflowNodeEntity.getAppId(), workflowNodeEntity.getFormId(), workflowNodeEntity.getMenuId(), workflowNodeEntity.getSaasMark(), workflowNodeEntity.getBusinessType(),
                    workflowNodeEntity.getUid(), workflowNodeEntity.getId(), workflowNodeEntity.getPrevId(), workflowNodeEntity.getWrapperId(), nodeCoreConfigurationPojo);
            List<Integer> nodeTypeList = Arrays.asList(WorkflowNodeTypeEnum.START_NODE.getType(), WorkflowNodeTypeEnum.CREATE_NODE.getType(),
                    WorkflowNodeTypeEnum.SINGLE_DATA_NODE.getType(), WorkflowNodeTypeEnum.UPDATE_NODE.getType());

            workflowNodeGetVO.setNodeList(getBeforeNodeListByNodeType(workflowNodeEntity.getCorpid(),
                    workflowNodeEntity.getWorkflowId(), workflowNodeEntity.getId(), nodeTypeList));
            return workflowNodeGetVO;
        } catch (Exception e) {
            LOGGER.error("WorkflowNodeSendMessageSettings.get error", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public WorkflowEnableVO check(WorkflowNodeEntity workflowNodeEntity, Map<Long, WorkflowNodeEntity> nodeMap, WorkflowGetPojo workflowGetPojo) throws XbbException {
        WorkflowEnableVO workflowEnableVO = new WorkflowEnableVO();
        SendMsgNode sendMsgNode = JSON.parseObject(workflowNodeEntity.getConfigData(), SendMsgNode.class);
        if (Objects.equals(workflowNodeEntity.getTriggerType(), WorkflowTriggerMethodEnum.FORM.getType())) {
            if (Objects.equals(1, sendMsgNode.getViewDetail()) && !nodeMap.containsKey(sendMsgNode.getWorkflowNodeId())) {
                return new WorkflowEnableVO(0, workflowNodeEntity.getId(), I18nMessageUtil.getMessage(ProErrorCodeEnum.API_ERROR_260036.getMsg()));
            }
            if (CollectionsUtil.isEmpty(sendMsgNode.getMessageRecipient())) {
                return new WorkflowEnableVO(0, workflowNodeEntity.getId(), I18nMessageUtil.getMessage("pojo.msg.SendMsgNode.messageRecipient.NotEmpty"));
            }
            if (CollectionsUtil.isEmpty(sendMsgNode.getMessageContent())) {
                return new WorkflowEnableVO(0, workflowNodeEntity.getId(), I18nMessageUtil.getMessage(MessageConstant.WORKFLOW_NODE_PAAS_MESSAGE_NULL));
            }
            for (WorkflowOptionalRangePojo item : sendMsgNode.getMessageRecipient()) {
                if (Objects.equals(item.getProperty(), OptionalRangeEnum.WORKFLOW_DYNAMIC_MANAGER.getValue())) {
                    if (!nodeMap.containsKey(item.getWorkflowNodeId())) {
                        return new WorkflowEnableVO(0, workflowNodeEntity.getId(), I18nMessageUtil.getMessage(ProErrorCodeEnum.API_ERROR_260036.getMsg()));
                    }
                    WorkflowNodeEntity node = nodeMap.get(item.getWorkflowNodeId());
                    if (!equals(item.getFormId(), item.getBusinessType(), node.getFormId(), node.getBusinessType())) {
                        // 表单不一致
                        return new WorkflowEnableVO(0, workflowNodeEntity.getId(), I18nMessageUtil.getMessage(ProErrorCodeEnum.API_ERROR_260042.getMsg()));
                    }
                }
            }
        }
        return workflowEnableVO;
    }


    @Override
    public void replaceWorkflowNodeId(WorkflowNodeEntityExt workflowNodeEntityExt, Map<Long, Long> workflowNodeMap) throws XbbException {
        SendMsgNode sendMsgNode = JSON.parseObject(workflowNodeEntityExt.getConfigData(), SendMsgNode.class);
        if (Objects.nonNull(sendMsgNode)) {
            if (Objects.nonNull(sendMsgNode.getWorkflowNodeId())) {
                sendMsgNode.setWorkflowNodeId(workflowNodeMap.get(sendMsgNode.getWorkflowNodeId()));
            }
            if (CollectionsUtil.isNotEmpty(sendMsgNode.getMessageRecipient())) {
                sendMsgNode.getMessageRecipient().forEach(item->{
                    if (Objects.equals(OptionalRangeEnum.WORKFLOW_DYNAMIC_MANAGER.getValue(), item.getProperty())) {
                        item.setWorkflowNodeId(workflowNodeMap.get(item.getWorkflowNodeId()));
                    }
                });
            }
            if (CollectionsUtil.isNotEmpty(sendMsgNode.getTitle())) {
                sendMsgNode.getTitle().forEach(item->{
                    if (Objects.nonNull(item.getWorkflowNodeId())) {
                        item.setWorkflowNodeId(workflowNodeMap.get(item.getWorkflowNodeId()));
                    }
                });
            }

            if (CollectionsUtil.isNotEmpty(sendMsgNode.getMessageContent())) {
                sendMsgNode.getMessageContent().forEach(item->{
                    if (Objects.nonNull(item.getWorkflowNodeId())) {
                        item.setWorkflowNodeId(workflowNodeMap.get(item.getWorkflowNodeId()));
                    }
                });
            }
            workflowNodeEntityExt.setConfigData(JSON.toJSONString(sendMsgNode));


        }
    }

    /**
     * 获取名称和头像
     * @param optionalRangeList
     * @param workflowGetPojo
     * @return com.xbongbong.workflow.pojo.WorkflowNodeTreePojo
     * @author 吴峰
     * @date 2021/5/24 15:07
     */

    private WorkflowNodeTreePojo getSendMsgNodeNameAndAvatar(List<WorkflowOptionalRangePojo> optionalRangeList, WorkflowGetPojo workflowGetPojo) {
        WorkflowNodeTreePojo workflowNodeTreePojo = new WorkflowNodeTreePojo();
        if (CollectionsUtil.isEmpty(optionalRangeList)) {
            return workflowNodeTreePojo;
        }
        Map<String, UserEntity> userMap = workflowGetPojo.getUserMap();
        Map<Integer, RoleEntity> roleMap = workflowGetPojo.getRoleMap();
        Map<Long, DepartmentEntity> departmentMap = workflowGetPojo.getDepartmentMap();
        List<String> nameList = new ArrayList<>();
        List<String> avatarList = new ArrayList<>();
        Map<Long, String> workflowNodeMap = workflowGetPojo.getWorkflowNodeMap();
        optionalRangeList.forEach(item->{
            if (Objects.equals(item.getProperty(), OptionalRangeEnum.USER.getValue())) {
                UserEntity userEntity = userMap.get(item.getId());
                nameList.add(userEntity.getName());
                avatarList.add(userEntity.getAvatar());
            } else if (Objects.equals(item.getProperty(), OptionalRangeEnum.DEPT.getValue())) {
                DepartmentEntity departmentEntity = departmentMap.get(Long.valueOf(item.getId()));
                nameList.add(departmentEntity.getName());
            }else if (Objects.equals(item.getProperty(), OptionalRangeEnum.ROLE.getValue())) {
                RoleEntity roleEntity = roleMap.get(Integer.valueOf(item.getId()));
                nameList.add(roleEntity.getRoleName());
            }else if (Objects.equals(item.getProperty(), OptionalRangeEnum.WORKFLOW_DYNAMIC_MANAGER.getValue())) {
                String name = item.getNodeName() + "-" + item.getName();
                if (workflowNodeMap.containsKey(item.getWorkflowNodeId())) {
                    name = workflowNodeMap.get(item.getWorkflowNodeId()) + "-";
                    name = name+item.getName();
                }
                nameList.add(name);
            }
        });
        List<String> contentList = new ArrayList<>();
        String name = String.format(I18nMessageUtil.getMessage(WorkflowConstant.SEND_MESSAGE_NODE), StringUtils.join(nameList, PaasConstant.COMMA));

        contentList.add(name);

        workflowNodeTreePojo.setContent(contentList);
        workflowNodeTreePojo.setAvatarList(avatarList);
        return workflowNodeTreePojo;
    }
}

